﻿using System.Collections.Generic;
using System.Linq;

namespace Shared.Service.DataScopes
{
    public static class DataScopesHelper
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataScopes"></param>
        /// <param name="dataScopeType"></param>
        /// <returns></returns>
        public static string[] GetScopeKeys(this IEnumerable<BaseDataScope> dataScopes, DataScopeType dataScopeType)
        {
            if (dataScopes.TryGetScopeKeys(dataScopeType, out var scopeKeys))
            {
                return scopeKeys;
            }

            return scopeKeys;
        }

        public static bool TryGetScopeKey(this IEnumerable<BaseDataScope> dataScopes, DataScopeType dataScopeType,
            out string scopeKey)
        {
            scopeKey = string.Empty;

            if (dataScopes.TryGetScopeKeys(dataScopeType, out var scopeKeys))
            {
                scopeKey = scopeKeys.SingleOrDefault();
                return true;
            }

            return false;
        }


        /// <summary>
        /// 获取组织权限中 组织机构中最大的层级
        /// </summary>
        /// <param name="dataScopes"></param>
        /// <returns></returns>
        public static DataScopeType TryGetMyMaxLevelOrg(this IEnumerable<BaseDataScope> dataScopes, bool inclueMySelf)
        {
            var baseDataScopes = dataScopes as BaseDataScope[] ?? dataScopes.ToArray();

            // 所有
            if (baseDataScopes.HasDataScope(DataScopeType.OrgAll))
            {
                return DataScopeType.OrgAll;
            }

            // 全国
            if (baseDataScopes.HasDataScope(DataScopeType.MyOrgCountry))
            {
                return DataScopeType.MyOrgCountry;
            }

            // 商户
            if (baseDataScopes.HasDataScope(DataScopeType.MyOrgArea))
            {
                return DataScopeType.MyOrgArea;
            }

            // 学校
            if (baseDataScopes.HasDataScope(DataScopeType.MyOrgSchool))
            {
                return DataScopeType.MyOrgSchool;
            }

            // 部门
            if (baseDataScopes.HasDataScope(DataScopeType.MyOrgDept))
            {
                return DataScopeType.MyOrgDept;
            }

            //个人
            if (inclueMySelf && baseDataScopes.HasDataScope(DataScopeType.Myself))
            {
                return DataScopeType.Myself;
            }

            return DataScopeType.Null;
        }

        public static bool TryGetScopeKeys(this IEnumerable<BaseDataScope> dataScopes, DataScopeType dataScopeType,
            out string[] scopeKeys)
        {
            var baseDataScopes = dataScopes as BaseDataScope[] ?? dataScopes.ToArray();

            switch (dataScopeType)
            {
                case DataScopeType.MyMaxLevelOrg:
                    return baseDataScopes.TryGetMyMaxLevelOrgScopeKeys(out scopeKeys);
                case DataScopeType.MyOrgs:
                    return baseDataScopes.TryGetMyOrgsScopeKeys(out scopeKeys);
                case DataScopeType.MyAllOrgs:
                    return baseDataScopes.TryGetMyAllOrgsScopeKeys(out scopeKeys);
                default:
                    return baseDataScopes.TryGetOtherScopeKeys(dataScopeType, out scopeKeys);
            }
        }

        public static bool HasDataScope(this IEnumerable<BaseDataScope> dataScopes, DataScopeType dataScopeType)
        {
            if (dataScopes == null)
            {
                return false;
            }

            return dataScopes.Any(ds => ds.ScopeType == dataScopeType);
        }

        #region 私有方法

        #region MyAllOrgs

        private static bool TryGetMyAllOrgsScopeKeys(this IEnumerable<BaseDataScope> dataScopes,
            out string[] scopeKeys)
        {
            var scopeKeyList = new List<string>();

            var result = false;
            // my 系列 组织架构
            var baseDataScopes = dataScopes as BaseDataScope[] ?? dataScopes.ToArray();

            if (baseDataScopes.TryGetMyOrgsScopeKeys(out var _scopeKeys))
            {
                result = true;

                scopeKeyList.AddRange(_scopeKeys);
            }

            if (baseDataScopes.TryGetOtherScopeKeys(DataScopeType.MyOtherOrgs, out _scopeKeys))
            {
                result = true;
                scopeKeyList.AddRange(_scopeKeys);
            }


            scopeKeys = scopeKeyList.Distinct().ToArray();
            return result;
        }

        #endregion

        #region MyOrgs 

        /// <summary>
        /// 获取用户的组织架构 对 全国，商户， 学校，部门 的叠加
        /// </summary>
        /// <param name="dataScopes"></param>
        /// <param name="scopeKeys"></param>
        /// <returns></returns>
        private static bool TryGetMyOrgsScopeKeys(this IEnumerable<BaseDataScope> dataScopes,
            out string[] scopeKeys)
        {
            var scopeKeyList = new List<string>();

            var result = false;

            // my 系列 组织架构
            var baseDataScopes = dataScopes as BaseDataScope[] ?? dataScopes.ToArray();

            // 国家
            if (baseDataScopes.TryGetOtherScopeKeys(DataScopeType.MyOrgCountry, out var _scopeKeys))
            {
                result = true;
                scopeKeyList.AddRange(_scopeKeys);
            }

            // 商户
            if (baseDataScopes.TryGetOtherScopeKeys(DataScopeType.MyOrgArea, out _scopeKeys))
            {
                result = true;
                scopeKeyList.AddRange(_scopeKeys);
            }

            // 学校
            if (baseDataScopes.TryGetOtherScopeKeys(DataScopeType.MyOrgSchool, out _scopeKeys))
            {
                result = true;
                scopeKeyList.AddRange(_scopeKeys);
            }

            // 部门
            if (baseDataScopes.TryGetOtherScopeKeys(DataScopeType.MyOrgDept, out _scopeKeys))
            {
                result = true;
                scopeKeyList.AddRange(_scopeKeys);
            }

            scopeKeys = scopeKeyList.Distinct().ToArray();
            return result;
        }

        #endregion

        #region MyMaxLevelOrg

        /// <summary>
        /// 获取用户策略配置的组织架构最高层级的Keys
        /// 优先国家 => 商户=> 学校=> 部门
        /// </summary>
        /// <param name="dataScopes"></param>
        /// <param name="scopeKeys"></param>
        /// <returns></returns>
        private static bool TryGetMyMaxLevelOrgScopeKeys(this IEnumerable<BaseDataScope> dataScopes,
            out string[] scopeKeys)
        {
            var baseDataScopes = dataScopes as BaseDataScope[] ?? dataScopes.ToArray();

            // 优先国家
            if (baseDataScopes.TryGetOtherScopeKeys(DataScopeType.MyOrgCountry, out scopeKeys))
            {
                return true;
            }

            // 商户
            if (baseDataScopes.TryGetOtherScopeKeys(DataScopeType.MyOrgArea, out scopeKeys))
            {
                return true;
            }

            // 学校
            if (baseDataScopes.TryGetOtherScopeKeys(DataScopeType.MyOrgSchool, out scopeKeys))
            {
                return true;
            }

            // 部门
            if (baseDataScopes.TryGetOtherScopeKeys(DataScopeType.MyOrgDept, out scopeKeys))
            {
                return true;
            }

            return false;
        }

        #endregion

        /// <summary>
        /// 获取其他的 范围
        /// </summary>
        /// <param name="dataScopes"></param>
        /// <param name="dataScopeType"></param>
        /// <param name="scopeKeys"></param>
        /// <returns></returns>
        private static bool TryGetOtherScopeKeys(this IEnumerable<BaseDataScope> dataScopes, DataScopeType dataScopeType,
            out string[] scopeKeys)
        {
            var dataScope = dataScopes?.FirstOrDefault(ds => ds.ScopeType == dataScopeType);

            if (dataScope == null)
            {
                scopeKeys = null;
                return false;
            }

            scopeKeys = dataScope.ScopeKeys;
            return true;
        }

        #endregion
    }
}
